package com.hello.util;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.commons.codec.binary.Base64;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.converter.PicturesManager;
import org.apache.poi.hwpf.converter.WordToHtmlConverter;
import org.apache.poi.hwpf.usermodel.PictureType;
import org.apache.poi.xwpf.converter.core.BasicURIResolver;
import org.apache.poi.xwpf.converter.xhtml.XHTMLConverter;
import org.apache.poi.xwpf.converter.xhtml.XHTMLOptions;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFPictureData;
import org.docx4j.Docx4J;
import org.docx4j.Docx4jProperties;
import org.docx4j.convert.out.HTMLSettings;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;

import com.hello.controller.FileToAction;

import fr.opensagres.xdocreport.core.io.internal.ByteArrayOutputStream;



public class OfficeUtil {
	private static final Logger log= LoggerFactory.getLogger(FileToAction.class);
	private final static String imgUrl = "officeUtil";

	/**
	 * 
	* @Title: docxToHTml 
	* @Description: TODO(docx文件转为html) HTML中图片与文档分离
	* @param @param fis
	* @param @param jurl
	* @param @return
	* @param @throws IOException    设定文件 
	* @return Office    返回类型 
	* @throws
	 */
	public static Office docxToHTml(FileInputStream fis, String jurl) throws IOException {
		Office office = new Office();
		OutputStreamWriter outputStreamWriter = null;
		try {
			XWPFDocument xdoc = new XWPFDocument(fis);
			XHTMLOptions options = XHTMLOptions.create();
			List<XWPFPictureData> pics = xdoc.getAllPictures();
			String fileId = UUID.randomUUID().toString().toUpperCase().replaceAll("-", "");
			List<BeanImage> images = new ArrayList<>();
			for (XWPFPictureData pic : pics) {
				String imgtype = pic.getFileName().substring(pic.getFileName().lastIndexOf(".")+1);
				BeanImage image = new BeanImage();
				image.setImgId(UUID.randomUUID().toString().toUpperCase().replaceAll("-", ""));
				image.setImgtype(imgtype.equalsIgnoreCase("jpg")?"jpeg":imgtype.toLowerCase());
				image.setImgName(pic.getFileName());
				image.setImgUrl(imgUrl+File.separator+fileId+File.separator+"word"+File.separator+"media"+pic.getFileName());
				image.setImgContent(pic.getData());
				images.add(image);
			}
			options.URIResolver(new BasicURIResolver(imgUrl+File.separator+fileId));
		    outputStreamWriter = new OutputStreamWriter(new FileOutputStream(jurl+File.separator+fileId+".html"), "UTF-8");
			XHTMLConverter xConverter = (XHTMLConverter) XHTMLConverter.getInstance(); 
			xConverter.convert(xdoc, outputStreamWriter, options);
			File f  = new File(jurl+File.separator+fileId+".html");
			office.setFileId(fileId);
			office.setImages(images);
			office.setHtml(f);
		} catch (IOException e) {
			e.printStackTrace();
			log.error("docx文档转html出现错误");
		} finally {
			 if (outputStreamWriter != null) { 
				 outputStreamWriter.close(); 
		    } 
		}
		return office;
	}
	
	public static Office docxToHtml2(FileInputStream fis, String jurl) throws IOException {
		Office office = new Office();
		try {
			WordprocessingMLPackage wordMLPackage = Docx4J.load(fis);
	        HTMLSettings htmlSettings = Docx4J.createHTMLSettings();
	        htmlSettings.setImageDirPath(jurl);
	        htmlSettings.setImageTargetUri("images"); // img 中 src 路径的上一级路径
	        htmlSettings.setWmlPackage(wordMLPackage);
	      /*  htmlSettings.setStyleElementHandler(new ConversionHTMLStyleElementHandler() {
				@Override
				public Element createStyleElement(OpcPackage opcPackage, Document document, String styleDefinition) {
					return null  ;
				}
			}); // 用户自己定义的 CSS*/	      
	        OutputStream os = new FileOutputStream(jurl);
	        Docx4jProperties.setProperty("docx4j.Convert.Out.HTML.OutputMethodXML", true);
	        Docx4J.toHTML(htmlSettings, os, Docx4J.FLAG_EXPORT_PREFER_XSL);
		} catch (IOException | Docx4JException e) {
			e.printStackTrace();
			log.error("docx文档转html出现错误");
		}
		return office;
	}
	
	
	/**
	* @Title: docToHTml 
	* @Description: TODO(doc格式word转为html) 
	* @param @param fis
	* @param @param jurl
	* @param @return    设定文件 
	* @return Office    返回类型 word文档中的图片转为base64
	* @throws
	 */
	public static Office docToHTml(FileInputStream fis, String jurl) {
		String fileId = UUID.randomUUID().toString().toUpperCase().replaceAll("-", "");
		Office office = new Office();
		try {
			HWPFDocument doc = new HWPFDocument(fis);
			WordToHtmlConverter wtc = new WordToHtmlConverter(DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument());
			wtc.setPicturesManager(new PicturesManager() {
				@Override
				public String savePicture(byte[] content, PictureType type, String name, float width, float height) {
					String imgtype = name.substring(name.lastIndexOf(".")+1);
					return "data:image/"+(imgtype.equalsIgnoreCase("jpg")?"jpeg":imgtype.toLowerCase())+";base64,"+Base64.encodeBase64String(content);
				}
			});
			wtc.processDocument(doc);
			
			Document document = wtc.getDocument();
			ByteArrayOutputStream outputStream  = new ByteArrayOutputStream();
			DOMSource domSource = new DOMSource(document);
			StreamResult streamResult = new StreamResult(outputStream);
			
			TransformerFactory tFactory = TransformerFactory.newInstance();
			Transformer transformer = tFactory.newTransformer();
			transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
			transformer.setOutputProperty(OutputKeys.INDENT, "yse");
			transformer.setOutputProperty(OutputKeys.METHOD, "html");
			transformer.transform(domSource, streamResult);
			
			File file = new File(jurl+File.separator+fileId+".html");
			FileOutputStream fileOutputStream = new FileOutputStream(file);
			BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(fileOutputStream,"UTF-8"));
			bufferedWriter.write(new String(outputStream.toByteArray()));
			office.setFileId(fileId);
			office.setHtml(file);
			outputStream.close();
			if (bufferedWriter!=null) {
				bufferedWriter.close();
			} 
			if (fileOutputStream!=null) {
				fileOutputStream.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
			log.error("doc文档转html出现错误");
		}
		return office;
	}
	
	/*基本返回类型
*/	public static class Office{
		private String fileId;
		private List<BeanImage> images;
		private File html;
		public void setFileId(String fileId) {
			this.fileId = fileId;
		}
		public void setImages(List<BeanImage> images) {
			this.images = images;
		}
		public void setHtml(File html) {
			this.html = html;
		}
		public String getFileId() {
			return fileId;
		}
		public List<BeanImage> getImages() {
			return images;
		}
		public File getHtml() {
			return html;
		}
		
	}
	
	/*基本图片类型*/	
 public static class BeanImage{
		private String imgId;
		private String imgtype;
		private String imgName;
		private byte[] imgContent;
		private String imgUrl;
		public void setImgId(String imgId) {
			this.imgId = imgId;
		}
		public void setImgtype(String imgtype) {
			this.imgtype = imgtype;
		}
		public void setImgName(String imgName) {
			this.imgName = imgName;
		}
		public void setImgContent(byte[] imgContent) {
			this.imgContent = imgContent;
		}
		public void setImgUrl(String imgUrl) {
			this.imgUrl = imgUrl;
		}
		public String getImgId() {
			return imgId;
		}
		public String getImgtype() {
			return imgtype;
		}
		public String getImgName() {
			return imgName;
		}
		public byte[] getImgContent() {
			return imgContent;
		}
		public String getImgUrl() {
			return imgUrl;
		}
		
	}
 
public static void wordTo(String data){
	try {
		WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.createPackage();  
		wordMLPackage.getMainDocumentPart().addParagraphOfText(data);  
		wordMLPackage.save(new java.io.File("D:/HelloWord.docx"));
	} catch (Docx4JException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}

/**
* @Title: fileEx 
* @Description: TODO(判断文件是否存在，不存在则创建) 
* @param @param path    设定文件 
* @return void    返回类型 
* @throws
 */
public static void fileEx(String path) {
	File file = new File(path);
	if (!file.exists()) {
	    try {
	        file.createNewFile();
	    } catch (IOException e) {
	        e.printStackTrace();
	    }
	    System.out.println("文件已创建");
	} else {
	    System.out.println("文件已存在");
	}
}

/**
* @Title: folderEx 
* @Description: TODO(判断文件夹是否存在，不存在则创建) 
* @param @param path    设定文件 
* @return void    返回类型 
* @throws
 */
public static void folderEx(String path) {
	File folder = new File(path);
	if (!folder.exists() && !folder.isDirectory()) {
	    folder.mkdirs();
	    System.out.println("创建文件夹");
	} else {
	    System.out.println("文件夹已存在");
	}
}

/**
 * @return 
* @Title: fileEx 
* @Description: TODO(判断文件是否存在，存在的话就在名字后面加一个（数字）) 
* @param @param path    设定文件 
* @return void    返回类型 
* @throws
 */
public static String fileExU(String path) {
	int index = 1 ;
	String ypath = path.substring(0, path.lastIndexOf("."));
	while (new File(path).exists()) {
		path = ypath + "("+index+").docx";
		index += 1;
	}
	return path;
}

}
